package cn.myframe.utils.file;

import cn.myframe.utils.DateUtils;
import org.apache.commons.lang.StringUtils;
import org.bytedeco.javacv.FFmpegFrameGrabber;
import org.bytedeco.javacv.Frame;
import org.bytedeco.javacv.Java2DFrameConverter;
import org.springframework.web.multipart.MultipartFile;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.*;
import java.nio.charset.Charset;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;

public class FileOperate {

    private static String SEPARATOR = "/";
    private static String SAVE_FILE_PATH = "giasfiles";

    public static String saveFile(String uploadParameter, String childrenFileName, MultipartFile[] files) {
        String path = SEPARATOR + SAVE_FILE_PATH + SEPARATOR + childrenFileName + SEPARATOR;
        if(!"demo".equals(childrenFileName)){
            path += DateUtils.format(new Date(), "yyyyMMdd");
        }
        String saveDirPath = uploadParameter + path;
        File saveDir = new File(saveDirPath);
        if (!saveDir.exists()) {
            saveDir.mkdirs();
        }
        String[] filePath = new String[files.length];
        if (files != null && files.length > 0) {
            for (int i = 0; i < files.length; i++) {
                int index = files[i].getOriginalFilename().lastIndexOf(".");
                String suffix = files[i].getOriginalFilename().substring(index);
                String fileName = System.currentTimeMillis() + i + suffix;
                String savePath = saveDirPath + SEPARATOR + fileName;
                downloadFile(files[i], savePath);
                filePath[i] = path + SEPARATOR + fileName;
            }
        }
        return String.join(";",filePath);
    }

    public static void downloadFile(MultipartFile file, String path) {
        BufferedInputStream in = null;
        BufferedOutputStream fo = null;
        try {
            if (file != null) {
                in = new BufferedInputStream(file.getInputStream());
                fo = new BufferedOutputStream(new FileOutputStream(new File(path)));
                byte[] arr = new byte[8 * 1024];
                int length;
                while ((length = in.read(arr)) != -1) {
                    fo.write(arr, 0, length);
                }
                if (file.getOriginalFilename().endsWith("mp4")) {
                    FFmpegFrameGrabber ff = new FFmpegFrameGrabber(path);
                    ff.start();
                    int videoSeconds = ff.getLengthInFrames();
                    Frame f = null;
                    int i = 0;
                    while (i < videoSeconds) {
                        f = ff.grabImage();
                        if ((i > 1) && (f.image != null)) {
                            break;
                        }
                        i++;
                    }
                    Java2DFrameConverter converter = new Java2DFrameConverter();
                    BufferedImage bufferedImage = converter.getBufferedImage(f);
                    ImageIO.write(bufferedImage, "jpg", new File(path.substring(0, path.indexOf("mp4")) + "jpg"));
                    ff.stop();
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            System.err.println("下载文件出错！");
        } finally {
            try {
                if (in != null) {
                    in.close();
                }
                if (fo != null) {
                    fo.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    public static void deleteFile(String path, String uploadParameter) {
        if (StringUtils.isNotEmpty(path) && !path.equals("undefined")) {
            String[] arr = path.split(";");
            for (String str : arr) {
                File file = new File(uploadParameter + str);
                if (file.exists()) {
                    file.delete();
                }
            }
        }
    }

    public static Map<String, String> uploadZip(String uploadPath, String childrenFileName, MultipartFile file) throws IOException {
        Map<String, String> resultMap = new HashMap<>();
        InputStream in = file.getInputStream();
        // 获取扩展名
        String originalFileName = file.getOriginalFilename();
        String ext = StringUtils.substringAfterLast(originalFileName,".");
        String fileName = originalFileName.substring(0, originalFileName.lastIndexOf("."));
        // 压缩包采用zip格式
        if (!"zip".equals(ext)) {
            resultMap.put("resultCode","fail");
            resultMap.put("fail","压缩包格式需为zip");
        }
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
        String nowStr = sdf.format(new Date());
        String path = SEPARATOR + SAVE_FILE_PATH + SEPARATOR + childrenFileName + SEPARATOR
                +DateUtils.format(new Date(), "yyyyMMdd")+SEPARATOR+ "zipFolder"+SEPARATOR;

        //素材压缩包的路径
        String carbonPath = uploadPath + path;
        File carbon = new File(carbonPath);
        if(!carbon.exists()){
            carbon.mkdirs();
        }
        //将上传的zip文件放到备份文件路径下
        String carbonFilePath = carbonPath + "/" + fileName + "_" + nowStr +"_zipfile." + ext;
        carbonFilePath = carbonFilePath.replaceAll("\\\\", "/");
        File originalFile = new File(carbonFilePath);
        // 进行流读写操作
        InputStream in0 = file.getInputStream();
        org.apache.commons.io.FileUtils.copyInputStreamToFile(in0, originalFile);

        //将zip包解压到当前的文件夹中
        Map<String, String> unMaterialZipMap = unMaterialZip(carbonFilePath);
        if(unMaterialZipMap.get("resultCode").equals("fail")){
            resultMap.put("resultCode","fail");
            resultMap.put("fail",unMaterialZipMap.get("fail"));
        }else{
            resultMap.put("resultCode","success");
            resultMap.put("success",path + SEPARATOR + fileName + "_" + nowStr+"_zipfile" + SEPARATOR + unMaterialZipMap.get("success"));
        }
     //   String rpath = carbonFilePath.substring(0, carbonFilePath.lastIndexOf(".")) + "/";
        return resultMap;
    }

    /**
     * 解压素材文件夹安装包
     *
     * @param filePath
     * @return
     */
    public static Map<String, String> unMaterialZip(String filePath) {
        boolean result = true;
        Map<String, String> resultMap = new HashMap<>();
        int numberOfHmtl = 0;  //html文件的数量，要求有且只有一个
        String htmlUrl = "";
        File source = new File(filePath);
        if (source.exists()) {
            String rpath = filePath.substring(0, filePath.lastIndexOf("."))
                    + "/";
            ZipInputStream zis = null;
            ZipInputStream zis1 = null;
            try {
                zis1 = new ZipInputStream(new FileInputStream(source),
                        Charset.forName("GBK"));

                ZipEntry entry = null;
                zis = new ZipInputStream(new FileInputStream(source));
                byte[] ch = new byte[256];
                while ((entry = zis1.getNextEntry()) != null) {
                    File zfile = new File(rpath + entry.getName());
                    File fpath = new File(zfile.getParentFile().getPath());
                    if (!entry.isDirectory()) {

                        String name = entry.getName().substring(
                                entry.getName().lastIndexOf("/") + 1,
                                entry.getName().length());
                        String suffixName = name.substring(
                                name.lastIndexOf(".") + 1, name.length());
                        if (suffixName.equals("html")){
                            numberOfHmtl++;
                            htmlUrl = entry.getName();
                            System.out.println("压缩包里面HTML文件的路径:"+ htmlUrl);
                        }

                        if (!fpath.exists()) {
                            fpath.mkdirs();
                        }
                        FileOutputStream fouts = new FileOutputStream(zfile);
                        int i;

                        while ((i = zis1.read(ch)) != -1) {
                            fouts.write(ch, 0, i);
                        }

                        fouts.close();
                        zis1.closeEntry();
                    }
                }
                zis.closeEntry();
            } catch (Exception e) {
                result = false;
            } finally {
                try {
                    if (zis != null) {
                        zis.close();
                    }
                    if (zis1 != null) {
                        zis1.close();
                    }

                } catch (IOException e) {
                    e.printStackTrace();
                }

            }
        }
        System.out.println("html文件的数量为："+numberOfHmtl);
        if(numberOfHmtl == 1 && result){
            resultMap.put("resultCode","success");
            resultMap.put("success",htmlUrl);
        }else{
            resultMap.put("resultCode","fail");
            if(!result){
                resultMap.put("fail","压缩包内容解压出错");
            }else{
                resultMap.put("fail","压缩包中应该有且仅有一个HTML文件");
            }
        }
        return resultMap;
    }

}
